initial commit
[AXOD IR_433MHz Shield] / FIRMWARE / uart.c
1 // -----------------------------------------------------------------------------------------------
2 // ------------------------------- UART serial data transfer -------------------------------------
3 // -----------------------------------------------------------------------------------------------
4
5 extern void read433_handler( void );
6
7 void    initserial(unsigned long baud);
8 char    kbhit(void);
9 char    getch(void);
10 char    getche(void);
11 void    putch(char c);
12 void    putstr(char *s);
13
14 static volatile uint8_t srx_done, stx_count;
15 static volatile uint8_t srx_data, srx_mask, srx_tmp, stx_data;
16
17 #define SRX_STR_MAX             30
18
19 // char         srx_str[SRX_STR_MAX];
20 uint8_t srx_cnt = 0;
21 uint8_t srx_ready = false;
22
23 struct COM_STRUCT {
24         char            pref[4];
25         char            space1;
26         char            dev[1];
27 //      char            space2;
28 //      char            qqq[3];
29         char            space3;
30         char            val[SRX_STR_MAX-7];
31 };
32
33 struct SHORT_COM_STRUCT {
34         char            pref[4];
35         char            space1;
36         char            val[SRX_STR_MAX-5];
37 };
38
39 union COM_UNION {
40         char                    str [SRX_STR_MAX];
41         struct COM_STRUCT       cmd;
42         struct SHORT_COM_STRUCT short_cmd;
43 };
44
45 union COM_UNION im;
46
47
48 // im.str = "IMFR";
49 // im.str = "IMLD";
50
51
52 // ------------------------------- serial strings and symbols transfer ---------------------------
53
54 char getch(void){
55         while (!srx_done);
56         srx_done = 0;
57         return srx_data;
58 }
59
60
61 char kbhit(void){
62         return srx_done;
63 }
64
65 void putch(char c){
66         while (stx_count);
67         stx_data = ~c;
68         stx_count = 10;
69 }
70
71 char getche(void) // echo 
72
73         char c = getch();
74         putch(c);
75         return c;
76 }
77
78 void putstr(char *s){
79         while (*s) putch(*s++);
80 }
81
82
83 void putstr_P(PGM_P str){
84         static PGM_P s;
85         s=str;
86         while ( pgm_read_byte(s) ) putch( pgm_read_byte(s++) );
87 }
88
89
90 //  ------------------------------------ low level UART --------------------------------------
91
92 static uint16_t bit_time, start_bit_time;
93
94 void initSerial(unsigned long baud)
95 {
96
97         set_output( DDRA,  TX );
98         output_high( PORTA, TX ); // TX
99         output_high( PORTA, RX ); // RX
100
101         bit_time = (F_CPU / 8) / baud ;
102         start_bit_time = bit_time + (bit_time >> 1);
103
104         // OCR1A        top value A for Counter1 
105         // TCNT1        8-bit register contains the value of Timer/Counter1
106
107         OCR1A = TCNT1 + 1;      // probably low bit of 16 bit timer value on a84
108
109         // TCCR1                Timer/Counter1 Control Register
110         // CS10                 prescaler none
111         // CS12                 prescaler CK/8
112         // CS10 + CS12          prescaler CK/16 (in PLL mode)
113         // COM1A1 + COM1A0      Set the OC1A output line on compare match
114
115 //      TCCR1 |= (1 << CS10) | (1 << CS12);
116 //      TCCR1 |= (1 << COM1A1) | (1 << COM1A0);
117
118         TCCR1B |= (1 << CS11);
119         TCCR1A |= (1 << COM1A1) | (1 << COM1A0);        // PA6? output TX
120
121         // OCIE1A       Timer/Counter1 Output Compare Match A Interrupt Enable
122
123 //      TIMSK |= (1 << OCIE1A);
124         TIMSK1 |= (1 << OCIE1A);
125
126         // PCMSK        Pin Change Enable Mask 0 (for RX)
127         // PCIE         Pin Change Interrupt Enable (for RX)    
128
129 //      PCMSK |= (1 << PCINT0);
130 //      GIMSK |= (1 << PCIE);
131
132         PCMSK0 |= (1 << PCINT7);
133         GIMSK |= (1 << PCIE0);                  // PCINT7..0 pin
134
135         stx_count = 0;
136         srx_done = 0;
137 }
138
139 // ISR(PCINT0_vect) // RX pin was pinged
140 ISR(PCINT0_vect) // RX pin was pinged           Pin change interrupt 0 (source 7, see above)
141 {
142         cli();
143         if ( PINA & (1 << RX) ) return;
144
145         // OCR1B        top value B for Counter1 
146         // TCNT1        8-bit register contains the value of Timer/Counter1
147
148         OCR1B = TCNT1 + (uint16_t) (start_bit_time);    // maybe OCR1BL 
149
150         srx_tmp = 0;
151         srx_mask = 1;
152
153         // TIFR         Timer/Counter Interrupt Flag Register
154         // OCF1B        bit is set (one) when compare match occurs in OCR1B - Output Compare Register 1A
155         // forsed interrupt execution ??? 
156         // TIFR = (1 << OCF1B);
157
158 //      TIFR |= (1 << OCF1B);
159         TIFR1 |= (1 << OCF1B);
160
161 //////  TIFR &= ~(1 << OCF1A); // added 
162
163         if ( !(PINA & (1 << RX)) ) {    // when RX not changed ???
164
165                 // Enable compare Timer/Counter1 Output Compare Match A & Match B Interrupt
166 ///////         TIMSK = (1 << OCIE1A) ^ (1 << OCIE1B);
167
168 //              TIMSK |= (1 << OCIE1A) | (1 << OCIE1B);
169                 TIMSK1 |= (1 << OCIE1A) | (1 << OCIE1B);
170
171 ///////         TIMSK &= ~(1 << TOIE1); // added
172
173 ///////         TIMSK |= (1 << OCIE1A);
174 ///////         TIMSK |= (1 << OCIE1B);
175
176                 // Pin Change disable Mask for PB0
177 //              PCMSK &= ~(1 << PCINT0);
178                 PCMSK0 &= ~(1 << PCINT7);
179         }
180         sei();
181 }
182
183
184 ISR(TIM1_COMPB_vect) // RX
185 {
186         cli();
187         uint8_t in = PINA;
188
189         if (srx_mask) {
190                 if (in & (1 << RX)) srx_tmp |= srx_mask;
191                 srx_mask <<= 1;
192                 // OCR1B        top value B for Counter1 
193                 OCR1B = OCR1B + bit_time;
194         } else {
195                 srx_done = 1;
196                 srx_data = srx_tmp;
197
198                 // collect string until '\n' (0x0a), for uninterruptable receiveing of strings
199 //              if ( srx_cnt < SRX_STR_MAX ) srx_str[ srx_cnt++ ] = srx_data;
200                 if ( srx_cnt < SRX_STR_MAX ) im.str[ srx_cnt++ ] = srx_data;
201                 if ( srx_data == 0x0a ) { 
202 //                      srx_str[ srx_cnt ] = 0;
203                         im.str[ srx_cnt ] = 0;
204                         srx_ready = true;
205                         srx_cnt = 0;
206                 }
207
208                 // Enable compare Timer/Counter1 Output Compare Match A Interrupt
209 //              TIMSK |= (1 << OCIE1A); 
210 //              TIMSK &= ~(1 << OCIE1B);
211
212                 TIMSK1 |= (1 << OCIE1A); 
213                 TIMSK1 &= ~(1 << OCIE1B);
214
215                 // Pin Change Enable Mask for PB0
216 //              PCMSK |= (1 << PCINT0);
217                 PCMSK0 |= (1 << PCINT7);
218         }
219         sei();
220 }
221
222
223 ISR(TIM1_COMPA_vect) // TX
224 {
225         cli();
226         uint8_t count;
227
228 //      PORTB ^= 0b100;         // check sampling frequency
229
230         // OCR1A        top value A for Counter1 
231         OCR1A = OCR1A + bit_time;
232
233         count = stx_count;
234
235         if (count) {
236                         stx_count = --count;
237
238                         if (count != 9) {
239
240                         if (!(stx_data & 1)) {
241                                 // Set OC1A output line (COM1A1 initially 1)
242 //                              TCCR1 |= (1 << COM1A0);
243                                 TCCR1A |= (1 << COM1A0);
244                         } else {
245                                 // Clear OC1A output line (COM1A1 initially 1)
246 //                              TCCR1 &= ~(1 << COM1A0);
247                                 TCCR1A &= ~(1 << COM1A0);
248                         }
249
250                         stx_data >>= 1;
251
252                 } else {
253                         // Clear OC1A output line (COM1A1 initially 1)
254 //                      TCCR1 &= ~(1 << COM1A0);
255                         TCCR1A &= ~(1 << COM1A0);
256                 }
257         } else {                
258                 read433_handler();
259                 pwm_scale_handler();
260 //              beep_handler();
261 //              pwm_handler();
262         }
263         sei();
264 }
265
Contact me: dev (at) shalnoff (dot) com
PGP fingerprint: A6B8 3B23 6013 F18A 0C71 198B 83D8 C64D 917A 5717